package boot

import (
	"encoding/base64"
	"errors"
	"fmt"
	"slices"
	"yunj/pkg/yunj/core/builder/builderdto"
	"yunj/pkg/yunj/core/validator"
	"yunj/pkg/yunj/util"

	"github.com/worklz/go-validate"
)

// 初始化验证器
func InitValidate() {

	// 获取area可选地区数据内容
	areaOptions := util.GetAreaOptions()

	// 注册验证规则
	validate.RegisterRules([]validate.Rule{
		{
			Name: "area",
			Fun: func(value interface{}, param string, datas map[string]interface{}, title string) (err error) {
				accSlice := []string{"province", "city", "district"}
				if param == "" {
					param = "district"
				}
				if !slices.Contains(accSlice, param) {
					err = errors.New(title + "验证规则 area 允许参数[province|city|district]")
					return
				}
				// fmt.Printf("123 %s %v %T", title, value, value)
				valueMap, ok := value.(map[string]any)
				if !ok {
					err = errors.New(title + "数据异常")
					return
				}
				provinceRaw, exists := valueMap["province"]
				provinceValue, ok := provinceRaw.(string)
				if !exists || !ok || provinceValue == "" {
					err = errors.New(title + "数据异常！请选择省份")
					return
				}
				provinceOptions, exists := (*areaOptions)["0"]
				if !exists || provinceOptions == nil {
					err = errors.New(title + "表单组件省份数据异常")
					return
				}
				if _, exists = provinceOptions[provinceValue]; !exists {
					err = errors.New(title + "省份数据异常")
					return
				}
				if param == "province" {
					return
				}

				cityRaw, exists := valueMap["city"]
				cityValue, ok := cityRaw.(string)
				if !exists || !ok || cityValue == "" {
					err = errors.New(title + "数据异常！请选择城市")
					return
				}
				cityOptions, exists := (*areaOptions)["0,"+provinceValue]
				if !exists || cityOptions == nil {
					err = errors.New(title + "表单组件城市数据异常")
					return
				}
				if _, exists = cityOptions[cityValue]; !exists {
					err = errors.New(title + "城市数据异常")
					return
				}
				if param == "city" {
					return
				}

				districtRaw, exists := valueMap["district"]
				districtValue, ok := districtRaw.(string)
				if !exists || !ok || districtValue == "" {
					err = errors.New(title + "数据异常！请选择区/县")
					return
				}
				districtOptions, exists := (*areaOptions)["0,"+provinceValue+","+cityValue]
				if !exists || districtOptions == nil {
					err = errors.New(title + "表单组件区/县数据异常")
					return
				}
				if _, exists = districtOptions[districtValue]; !exists {
					err = errors.New(title + "区/县数据异常")
					return
				}
				return
			},
		},
		{
			Name: "table",
			Fun: func(value interface{}, param string, datas map[string]interface{}, title string) (err error) {
				valItems, ok := value.([]any)
				if !ok {
					err = errors.New(title + "格式错误")
					return
				}
				if param == "" {
					err = errors.New(title + "验证规则table:参数不能为空")
					return
				}

				paramByte, err := base64.StdEncoding.DecodeString(param)
				if err != nil {
					err = errors.New(title + "验证规则table:参数错误")
					return
				}

				cols, err := util.JsonTo[[]builderdto.FormTableCol](string(paramByte))
				if err != nil {
					err = errors.New(title + "验证规则table:参数异常")
					return
				}

				v := &validator.Validator{}
				v.InitValidator(v)
				vRules := map[string]any{}
				vTitle := map[string]string{}
				for _, col := range cols {
					vRules[col.Field] = col.Verify
					vTitle[col.Field] = col.Title
				}

				for i, itemRaw := range valItems {
					rowDesc := fmt.Sprintf("第%d行", i+1)
					item, ok := itemRaw.(map[string]any)
					if !ok {
						err = errors.New(title + rowDesc + "数据格式错误")
						return
					}
					if len(item) == 0 {
						err = errors.New(title + rowDesc + "数据为空")
						return
					}

					for _, col := range cols {
						if _, exists := item[col.Field]; !exists {
							err = errors.New(title + rowDesc + "需所有表头传值")
							return
						}
					}

					if err = util.DatasValidate(v, item, vRules, vTitle, ""); err != nil {
						err = errors.New(title + rowDesc + err.Error())
						return
					}
				}
				return
			},
		},
	})
}
